#ifndef MODULE_H
#define MODULE_H
#include <memory>
#include <atomic>
#include <thread>

#include "Module/Module.h"
#include "MxBase/E2eInfer/ImageProcessor/ImageProcessor.h"
#include "MxBase/E2eInfer/VideoDecoder/VideoDecoder.h"
#include "MxBase/E2eInfer/VideoEncoder/VideoEncoder.h"
#include "MxBase/E2eInfer/DataType.h"

#include "MxBase/MxBase.h"
#include "MxBase/Log/Log.h"

enum RunMode {
    READY = 0,
    RUNNING,
    STOPPED
};

class Module {
public:
    Module() = default;
    Module(const std::string &inputName, const std::string &outputName) : 
        inputPort_(inputName), outputPort_(outputName) {};
    virtual ~Module() {};
    void SetInput(const std::string &inputName);
    void SetOutput(const std::string &outputName);
    virtual APP_ERROR Init() = 0;
    virtual APP_ERROR Process(const std::shared_ptr<void> &input) = 0;
    virtual APP_ERROR DeInit() = 0;
    virtual std::string GetModuleName() = 0;
    APP_ERROR SendData(const std::shared_ptr<void> &data);
    APP_ERROR Start(bool getFPS = false);
    APP_ERROR Stop();
    RunMode Status() const;
    

private:
    APP_ERROR GetData(std::shared_ptr<void> &data);
    void Run();
    void Fps();

private:
    RunMode status_ = RunMode::READY;
    std::string moduleName_ = "Module";
    std::string inputPort_ = "";
    std::string outputPort_ = "";
    std::vector<std::thread> threads_;
    std::atomic<uint32_t> count_;
};


#endif